using BCCommon;
using BCCommon.Enums;
using BCCommon.Enums.Driver;
using BCCommon.Extensions;
using BCCommon.PaymentEnums;
using BCCommon.TMS.Driver;
using BCCommon.TMS.Order;
using BCCommon.TMS.Transport;
using BCData.Common.FlowRecord;
using BCData.Common.Payment.Payment;
using BCData.Common.PushMessageConfig;
using BCData.TMS.Driver;
using BCData.TMS.NotificationMessageRecord;
using BCData.TMS.Order.Order;
using BCData.TMS.Order.OrderAssignRecord;
using BCData.TMS.Order.OrderExtention;
using BCData.TMS.Order.OrderPool;
using BCData.TMS.TransportOrder;
using BCData.TMS.VehicleCategoryReference;
using BCData.Website.User.User;
using BCDto.Common.Payment.Payment;
using BCDto.Common.SystemFinanceFlowRecord;
using BCDto.Common.Wallet;
using BCDto.Location;
using BCDto.Sim.Admin.Admin;
using BCDto.TMS.Driver;
using BCDto.TMS.Order;
using BCDto.TMS.Order.Order;
using BCDto.TMS.Order.OrderEvaluation;
using BCDto.TMS.Order.OrderExtention;
using BCDto.TMS.Order.OrderProcess;
using BCDto.Website.User;
using BCEntity.Common.EntityNameConst;
using BCEntity.Common.FlowRecord;
using BCEntity.Common.Payment.Payment;
using BCEntity.TMS.Driver;
using BCEntity.TMS.NotificationMessageRecord;
using BCEntity.TMS.Order.Order;
using BCEntity.TMS.Order.OrderAssignRecord;
using BCEntity.TMS.Order.OrderExtention;
using BCEntity.Website.User;
using BCService.Common.Payment.Payment;
using BCService.Common.PushMessage.PushMessageSend;
using BCService.Common.SystemConfiguration;
using BCService.Common.SystemFinanceFlowRecord;
using BCService.Common.Wallet;
using BCService.TMS.Order.OrderCancelRecord;
using BCService.TMS.Order.OrderEvaluation;
using BCService.TMS.TransportOrder;
using BCService.TMS.VehicleSuiteBusinessConfig;
using BCService.Utils;
using System;
using System.Collections.Generic;
using System.Linq;

namespace BCService.TMS.Order.Order
{
    public class OrderProcessService : IOrderProcessService
    {
        private readonly IOrderData orderData;
        private readonly IOrderExtentionData orderExtentionData;
        private readonly IVehicleCategoryReferenceData vehicleCategoryReferenceData;
        private readonly IRedisService redisService;
        private readonly IDriverData driverData;
        private readonly IOrderAssignRecordData orderAssignRecordData;
        private readonly IPaymentRecordData paymentRecordData;
        private readonly IPushMessageConfigData pushMessageConfigData;
        private readonly ITransportOrderData transportOrderData;
        private readonly ISystemConfigurationService systemConfigurationService;
        private readonly IDatabaseContext databaseContext;
        private readonly INotificationMessageRecordData notificationMessageRecordData;
        private readonly ISystemFinanceFlowRecordService systemFinanceFlowRecordService;
        private readonly IWalletService walletService;
        private readonly IUserFlowRecordData userFlowRecordData;
        private readonly IUserData userData;
        private readonly IPushMessageSendService pushMessageSendService;
        private readonly IOrderPoolData orderPoolData;
        private readonly IOrderEvaluationService orderEvaluationService;
        private readonly IOrderCancelRecordService orderCancelRecordService;
        private readonly string key = string.Format("{0}", EntityNameConst.OrderEntity);
        private readonly ITransportOrderService transportOrderService;
        private readonly IVehicleSuiteBusinessConfigService vehicleSuiteBusinessConfigService;

        public OrderProcessService(IOrderData orderData,
            IOrderExtentionData orderExtentionData,
            IVehicleCategoryReferenceData vehicleCategoryReferenceData,
            IRedisService redisService,
            IDriverData driverData,
            IOrderAssignRecordData orderAssignRecordData,
            IPaymentRecordData paymentRecordData,
            IPushMessageConfigData pushMessageConfigData,
            ITransportOrderData transportOrderData,
            ISystemConfigurationService systemConfigurationService,
            IDatabaseContext databaseContext,
            INotificationMessageRecordData notificationMessageRecordData,
            ISystemFinanceFlowRecordService systemFinanceFlowRecordService,
            IWalletService walletService,
            IUserFlowRecordData userFlowRecordData,
            IUserData userData,
            IPushMessageSendService pushMessageSendService,
            IOrderPoolData orderPoolData,
            IOrderEvaluationService orderEvaluationService,
            IOrderCancelRecordService orderCancelRecordService,
            ITransportOrderService transportOrderService,
            IVehicleSuiteBusinessConfigService vehicleSuiteBusinessConfigService)
        {
            this.orderData = orderData;
            this.orderExtentionData = orderExtentionData;
            this.vehicleCategoryReferenceData = vehicleCategoryReferenceData;
            this.redisService = redisService;
            this.driverData = driverData;
            this.orderAssignRecordData = orderAssignRecordData;
            this.paymentRecordData = paymentRecordData;
            this.pushMessageConfigData = pushMessageConfigData;
            this.transportOrderData = transportOrderData;
            this.systemConfigurationService = systemConfigurationService;
            this.databaseContext = databaseContext;
            this.notificationMessageRecordData = notificationMessageRecordData;
            this.systemFinanceFlowRecordService = systemFinanceFlowRecordService;
            this.walletService = walletService;
            this.userFlowRecordData = userFlowRecordData;
            this.userData = userData;
            this.pushMessageSendService = pushMessageSendService;
            this.orderPoolData = orderPoolData;
            this.orderEvaluationService = orderEvaluationService;
            this.orderCancelRecordService = orderCancelRecordService;
            this.transportOrderService = transportOrderService;
            this.vehicleSuiteBusinessConfigService = vehicleSuiteBusinessConfigService;
        }

        public OrderDto GetOrder(string orderNo)
        {
            OrderEntity orderEntity = this.redisService.TryGet(string.Format("{0}:OrderNo={1}", EntityNameConst.OrderEntity, orderNo), () =>
            {
                return this.orderData.GetEntity(orderNo).GetAwaiter().GetResult();
            }, TimeSpan.FromMinutes(10));
            if (orderEntity == null)
            {
                throw new ArgumentException("此订单不存在");
            }
            List<OrderExtentionDto> orderExtentionDtos = GetOrderExtentionDtos(orderEntity.OrderNo);
            if (!orderExtentionDtos.Any())
            {
                throw new ArithmeticException("订单信息请求失败");
            }
            OrderDto orderDto = orderEntity.As<OrderDto>();
            orderDto.OrderExtentionInfo = orderExtentionDtos;
            return orderDto;
        }
        public OrderDto GetOrder(long orderId)
        {
            OrderEntity orderEntity = this.redisService.TryGet(string.Format("{0}:OrderId={1}", EntityNameConst.OrderEntity, orderId), () =>
            {
                return this.orderData.GetEntity(orderId).GetAwaiter().GetResult();
            }, TimeSpan.FromMinutes(10));
            if (orderEntity == null)
            {
                throw new ArgumentException("此订单不存在");
            }
            List<OrderExtentionDto> orderExtentionDtos = GetOrderExtentionDtos(orderEntity.OrderNo);
            if (!orderExtentionDtos.Any())
            {
                throw new ArithmeticException("订单信息请求失败");
            }
            OrderDto orderDto = orderEntity.As<OrderDto>();
            orderDto.OrderExtentionInfo = orderExtentionDtos;
            return orderDto;
        }

        public OrderDto GetWithUser(long userId, long orderId)
        {
            string cacheKey = this.redisService.GetKey(key, userId, orderId);
            var result = this.redisService.TryGet(cacheKey, () =>
            {
                var data = this.orderData.GetEntityWithUser(userId, orderId).GetAwaiter().GetResult().As<OrderDto>();
                return data;
            }, TimeSpan.FromDays(1));
            return result;
        }

        public OrderDto GetWithDriver(long driverId, long orderId)
        {
            string cacheKey = this.redisService.GetKey(key, driverId, orderId);
            var result = this.redisService.TryGet(cacheKey, () =>
            {
                var data = this.orderData.GetEntityWithDriver(driverId, orderId).GetAwaiter().GetResult().As<OrderDto>();
                if (data != null)
                {
                    data.OrderExtentionInfo = this.GetOrderExtentionDtos(data.OrderNo);
                }
                return data;
            }, TimeSpan.FromDays(1));
            return result;
        }

        #region 获取订单信息--分页查询
        /// <summary>
        /// 用户端App独立使用查询订单列表
        /// </summary>
        /// <param name="userAppOrderStatus">用户端App订单状态</param>
        /// <param name="userId">用户Id</param>
        /// <param name="pageIndex">当前页码</param>
        /// <param name="pageSize">每页数据条数</param>
        /// <returns></returns>
        public PageableList<OrderDto> ClientAppQueryOrders(UserAppOrderStatus userAppOrderStatus, long? userId, int pageIndex, int pageSize)
        {
            var (list, count) = this.orderData.GetOrderEntities(userAppOrderStatus, userId, pageIndex, pageSize).GetAwaiter().GetResult();

            var orderEntities = list.As<IEnumerable<OrderDto>>();

            List<OrderDto> orderList = new List<OrderDto>();

            ////订单选择全部或者关闭时，增加总量订单到订单列表顶部
            //if (userAppOrderStatus == UserAppOrderStatus.All || userAppOrderStatus == UserAppOrderStatus.Complete)
            //{
            //    IEnumerable<OrderAggregateEntity> orderAggregateEntities = this.orderAggregateData.QueryByUserId(userId.Value, userAppOrderStatus).GetAwaiter().GetResult();

            //    IEnumerable<OrderDto> orderDtos = orderAggregateEntities.As<IEnumerable<OrderDto>>();
            //    foreach (OrderDto item in orderDtos)
            //    {
            //        item.IsAggregate = true;
            //        IEnumerable<OrderAggregateExtentionEntity> orderAggregateExtentionEntities = this.orderAggregateExtentionData.Query(item.OrderAggregateNo).GetAwaiter().GetResult();
            //        item.OrderExtentionInfo = orderAggregateExtentionEntities.As<List<OrderExtentionDto>>();
            //        orderList.Add(item);
            //    }
            //}

            foreach (OrderDto item in orderEntities)
            {
                item.OrderExtentionInfo = GetOrderExtentionDtos(item.OrderNo);

                orderList.Add(item);
            }

            return new PageableList<OrderDto>()
            {
                Items = orderList,
                Count = count,
                PageIndex = pageIndex,
                PageSize = pageSize,
                ServerTime = DateTime.Now
            };
        }

        #endregion

        #region 司机端App独立使用
        /// <summary>
        /// 司机端App独立使用查询订单列表
        /// </summary>
        /// <param name="driverAppOrderStatus">司机端App订单状态</param>
        /// <param name="driverId">司机Id</param>
        /// <param name="pageIndex">当前页码</param>
        /// <param name="pageSize">每页数据条数</param>
        /// <returns></returns>
        public PageableList<OrderDto> DriverAppQueryOrders(DriverAppOrderStatus driverAppOrderStatus, long? driverId, int pageIndex, int pageSize)
        {
            var (list, count) = this.orderData.GetOrderEntities(driverAppOrderStatus, driverId, pageIndex, pageSize).GetAwaiter().GetResult();

            var orderEntities = list.As<IEnumerable<OrderDto>>();

            foreach (OrderDto item in orderEntities)
            {
                item.OrderExtentionInfo = GetOrderExtentionDtos(item.OrderNo);
            }

            return new PageableList<OrderDto>
            {
                Items = orderEntities,
                Count = count,
                PageIndex = pageIndex,
                PageSize = pageSize,
                ServerTime = DateTime.Now
            };
        }

        public PageableList<OrderDto> DriverAppQueryPendingOrders(DriverDto driver, TransportBusinessType? transportBusinessType, int pageIndex, int pageSize)
        {
            var (list, count) = this.orderData.GetOrderEntities(driver.As<DriverEntity>(), OrderStatus.PlaceOrder, transportBusinessType, pageIndex, pageSize).GetAwaiter().GetResult();

            var orderEntities = list.As<IEnumerable<OrderDto>>();

            foreach (OrderDto item in orderEntities)
            {
                item.OrderExtentionInfo = GetOrderExtentionDtos(item.OrderNo);
            }

            return new PageableList<OrderDto>
            {
                Items = orderEntities,
                Count = count,
                PageIndex = pageIndex,
                PageSize = pageSize,
                ServerTime = DateTime.Now
            };
        }

        #region 修改订单装卸货地址状态--已到达

        public bool UpdateOrderExtentionAddressStatus(DriverDto driverDto, long orderId, CoordinateBsonDto coordinateDto, bool? adminOperation)
        {
            OrderDto orderDto = this.GetOrder(orderId);
            if (driverDto.VehicleTypeId != orderDto.VehicleTypeId)
            {
                throw new ArgumentException("您无法操作不属于您的订单");
            }
            List<OrderExtentionDto> orderExtentionDtos = GetOrderExtentionDtos(orderDto.OrderNo);
            if (!orderExtentionDtos.Any())
            {
                return true;
            }
            long orderExtentionInfoId = 0;
            //系统配置
            var systemConfig = this.systemConfigurationService.Get();
            foreach (OrderExtentionDto item in orderExtentionDtos)
            {
                double dis = CoordinateUtils.CoordinateDifference(coordinateDto.Longitude, coordinateDto.Latitude, item.EndLongitude, item.EndLatitude);
                if (item.AddressType == AddressType.Take)
                {
                    switch (orderDto.TransportBusiness.As<TransportBusinessType>())
                    {
                        case TransportBusinessType.RunErrands:
                        case TransportBusinessType.SmallPieces:
                            if (systemConfig.EnableHorsemanPickupDistanceLimit && systemConfig.HorsemanPickupDistanceLimit > 0)
                            {
                                if (dis > systemConfig.HorsemanPickupDistanceLimit)
                                {
                                    throw new ArgumentException($"距离到店还有{systemConfig.HorsemanPickupDistanceLimit / 1000}公里内,无法完成已到达操作");
                                }
                            }
                            break;
                        case TransportBusinessType.Moving:
                        case TransportBusinessType.SameCity:
                            if (systemConfig.EnableVehiclePickupDistanceLimit && systemConfig.VehiclePickupDistanceLimit > 0)
                            {
                                if (dis > systemConfig.VehiclePickupDistanceLimit)
                                {
                                    throw new ArgumentException($"距离发货还有{systemConfig.VehiclePickupDistanceLimit / 1000}公里内,无法完成已到达操作");
                                }
                            }
                            break;
                        default:
                            break;
                    }

                    if (item.OrderStatus == OrderStatus.Arrived)
                    {
                        return true;
                    }
#if DEBUG
                    if (item.OrderStatus == OrderStatus.Pickup)
                    {
                        orderExtentionInfoId = item.OrderExtentionId;
                        break;
                    }
#else
                    if(adminOperation.HasValue&& adminOperation.Value)
                    {
                        if (item.OrderStatus == OrderStatus.Pickup)
                        {
                            orderExtentionInfoId = item.OrderExtentionId;
                            break;
                        }
                    }
                    if (item.OrderStatus == OrderStatus.Pickup && dis < 500000)
                    {
                        orderExtentionInfoId = item.OrderExtentionId;
                        break;
                    }
#endif

                }
                else
                {
                    if (item.OrderStatus == OrderStatus.Arrived)
                    {
                        return true;
                    }
#if DEBUG
                    if (item.OrderStatus == OrderStatus.Transporting)
                    {
                        orderExtentionInfoId = item.OrderExtentionId;
                        break;
                    }
#else
                    if(adminOperation.HasValue&& adminOperation.Value)
                    {
                        if (item.OrderStatus == OrderStatus.Transporting)
                        {
                            orderExtentionInfoId = item.OrderExtentionId;
                            break;
                        }
                    }
                    if (item.OrderStatus == OrderStatus.Transporting && CoordinateUtils.CoordinateDifference(coordinateDto.Longitude, coordinateDto.Latitude, item.EndLongitude, item.EndLatitude) < 500000)
                    {
                        orderExtentionInfoId = item.OrderExtentionId;
                        break;
                    }
#endif
                }
            }
            this.databaseContext.BeginTransaction();
            var task = this.orderExtentionData.UpdateOrderStatusArrived(orderDto.OrderNo, orderExtentionInfoId).GetAwaiter().GetResult();
            int maxIndex = orderExtentionDtos.Max(p => p.EndIndex);
            int minIndex = orderExtentionDtos.Min(p => p.EndIndex);
            OrderExtentionDto orderExtentionDto = orderExtentionDtos.Single(p => p.EndIndex == maxIndex);
            OrderExtentionDto orderExtentionMinDto = orderExtentionDtos.Single(p => p.EndIndex == minIndex);
            if (orderExtentionDto.OrderExtentionId == orderExtentionInfoId)
            {
                this.orderData.UpdateOrderStatusArrived(orderDto.OrderId);
                this.RemoveOrderCatch(orderId);
            }
            else
            {
                if (orderExtentionMinDto.EndIndex == minIndex)
                {
                    this.orderData.UpdateOrderStatusArrived(orderDto.OrderId);
                    this.RemoveOrderCatch(orderId);
                }
            }
            this.databaseContext.Commit();
            this.RemoveOrderCatch(orderId);
            return true;

        }
        #endregion

        #region 司机装货
        public OrderDto OrderLoading(DriverDto driverDto, OrderLoadingRequestDto orderLoadingRequestDto)
        {
            OrderDto orderDto = this.GetOrder(orderLoadingRequestDto.OrderNo);
            if (orderDto == null)
            {
                throw new ArgumentException("订单信息不存在");
            }
            if (orderDto.OrderStatus == OrderStatus.Cancel)
            {
                throw new ArgumentException("订单已取消，无法完成装货操作");
            }
            if (orderDto.OrderStatus == OrderStatus.Complete)
            {
                throw new ArgumentException("订单已完成，无法完成装货操作");
            }
            if (orderDto.OrderStatus == OrderStatus.Dispatching)
            {
                throw new ArgumentException("订单未指派车辆，无法完成装货操作");
            }
            if (orderDto.DriverId != driverDto.DriverId)
            {
                throw new ArgumentException("您无法操作其他司机订单");
            }
            if (orderLoadingRequestDto.OrderExtentionId <= 0)
            {
                throw new ArgumentException("订单扩展地址信息不能为空");
            }
            if (!orderDto.OrderExtentionInfo.Any(p => p.OrderExtentionId == orderLoadingRequestDto.OrderExtentionId))
            {
                throw new ArgumentException("订单内不存在此地址信息，无法完成装货操作");
            }
            OrderExtentionDto orderExtentionDto = orderDto.OrderExtentionInfo.Single(p => p.OrderExtentionId == orderLoadingRequestDto.OrderExtentionId);
            if (orderExtentionDto.AddressType == AddressType.Place)
            {
                throw new ArgumentException("此地址为卸货地，无法完成装货操作");
            }
            if (orderExtentionDto.OrderStatus == OrderStatus.Transporting)
            {
                throw new ArgumentException("此订单已在运输中，无需重复装货操作");
            }
            if (orderExtentionDto.OrderStatus != OrderStatus.Arrived)
            {
                throw new ArgumentException("并未到达此地址，无法完成装货操作");
            }
            OrderExtentionEntity orderExtentionEntity = orderExtentionDto.As<OrderExtentionEntity>();
            orderExtentionEntity.LoadPhotoLeft = orderLoadingRequestDto.LoadPhotoLeft;
            orderExtentionEntity.LoadPhotoFront = orderLoadingRequestDto.LoadPhotoFront;
            orderExtentionEntity.LoadPhotoBack = orderLoadingRequestDto.LoadPhotoBack;
            orderExtentionEntity.LoadPhotoShipping = orderLoadingRequestDto.LoadPhotoShipping;
            if (!this.orderExtentionData.UpdateLoadingGoods(orderExtentionEntity).GetAwaiter().GetResult())
            {
                throw new ArgumentException("补充订单装货信息失败!");
            }
            string key = string.Format("{0}:OrderNo={1}", EntityNameConst.OrderExtentionEntities, orderDto.OrderNo);
            this.redisService.DeleteAsync(key);
            return GetOrder(orderDto.OrderId);
        }

        #endregion 司机出发

        #region 司机出发

        public OrderDto StartOut(DriverDto driverDto, OrderStartOutRequestDto orderStartOutRequestDto)
        {
            OrderDto orderDto = this.GetOrder(orderStartOutRequestDto.OrderNo);
            if (orderDto == null)
            {
                throw new ArgumentException("订单信息不存在");
            }
            if (orderDto.OrderStatus == OrderStatus.Cancel)
            {
                throw new ArgumentException("订单已取消，无法完成出发操作");
            }
            if (orderDto.OrderStatus == OrderStatus.Complete)
            {
                throw new ArgumentException("订单已完成，无法完成出发操作");
            }
            if (orderDto.OrderStatus == OrderStatus.Dispatching)
            {
                throw new ArgumentException("订单未指派车辆，无法完成出发操作");
            }
            if (orderDto.DriverId != driverDto.DriverId)
            {
                throw new ArgumentException("您无法操作其他司机订单");
            }
            if (!orderDto.OrderExtentionInfo.Any(p => p.OrderExtentionId == orderStartOutRequestDto.OrderExtentionId))
            {
                throw new ArgumentException("订单内不存在此地址信息，无法完成出发操作");
            }
            OrderExtentionDto orderExtentionDto = orderDto.OrderExtentionInfo.Single(p => p.OrderExtentionId == orderStartOutRequestDto.OrderExtentionId);
            if (orderStartOutRequestDto.AddressType == AddressType.Take)
            {
                if (orderExtentionDto.AddressType == AddressType.Place)
                {
                    throw new ArgumentException("此地址为卸货地，无法完成出发操作");
                }
            }
            if (orderExtentionDto.OrderStatus == OrderStatus.Transporting)
            {
                return GetOrder(orderDto.OrderId);
            }
            if (orderExtentionDto.OrderStatus != OrderStatus.Arrived)
            {
                throw new ArgumentException("并未到达此地址，无法完成出发操作");
            }

            int beginIndex = orderDto.OrderExtentionInfo.Min(p => p.EndIndex);
            if (orderDto.OrderExtentionInfo.Count(p => p.EndIndex == beginIndex) > 1)
            {
                throw new ArgumentException("订单信息错误，存在多个起始地");
            }

            #region 检查是否装现付订单

            if (orderDto.PayMode == PayMode.CurrentlyPay)
            {
                if (orderExtentionDto.EndIndex == beginIndex)
                {
                    if (!orderDto.ShippingPayTime.HasValue)
                    {
                        throw new ArgumentException("现付订单，请先完成订单运费支付");
                    }
                }
            }

            #endregion 检查是否现付订单

            #region 检查原始回单

            if (orderDto.PayMode == PayMode.PaidReceipt)
            {
                if (orderExtentionDto.EndIndex == beginIndex)
                {
                    if (string.IsNullOrWhiteSpace(orderDto.ReceiptPhoto))
                    {
                        throw new ArgumentException("回单付订单，请先上传回单原始凭证");
                    }
                }
            }

            #endregion 检查原始回单
            this.databaseContext.BeginTransaction();

            if (!this.orderExtentionData.UpdateOrderStatusTransporting(orderStartOutRequestDto.OrderNo, orderStartOutRequestDto.OrderExtentionId).GetAwaiter().GetResult())
            {
                throw new ArgumentException("修改订单途经点状态为运输中时失败!");
            }
            if (!this.orderData.UpdateOrderStatusTransporting(orderDto.OrderId).GetAwaiter().GetResult())
            {
                throw new ArgumentException("修改订单状态为运输中时失败!");
            }
            if (orderDto.OrderExtentionInfo.Count(p => p.AddressType == AddressType.Take) == 1 ||
                orderDto.OrderExtentionInfo.Count(p => p.AddressType == AddressType.Take && p.OrderStatus == OrderStatus.Transporting) == orderDto.OrderExtentionInfo.Count(p => p.AddressType == AddressType.Take))
            {
                if (!this.orderExtentionData.UpdateOrderStatusTransporting(orderStartOutRequestDto.OrderNo).GetAwaiter().GetResult())
                {
                    throw new ArgumentException("修改订单装货地状态为运输中时失败!");
                }
            }

            this.databaseContext.Commit();
            this.RemoveOrderCatch(orderDto.OrderId);
            return GetOrder(orderDto.OrderId);
        }

        #endregion 司机出发

        #region 创建订单支付二维码

        public PaymentQRCodeDto CreatePaymentQRCode(SourceAppType appType, UserDto user, DriverDto vehicleDto, PaymentRequestDto paymentRequestDto, IChannelFactoryService channelFactoryService)
        {
            OrderDto order = this.GetOrder(paymentRequestDto.ReferenceNumber);

            if (order == null || order.VehicleTypeId != vehicleDto.VehicleTypeId)
            {
                throw new ArgumentException($"找不到编号为 {paymentRequestDto.ReferenceNumber} 的订单");
            }
            if (order.PayMode == PayMode.PaidReceipt)
            {
                if (!order.IsCod)
                {
                    throw new ArgumentException("回单付订单无法执行此操作");
                }
            }
            if (order.PayMode == PayMode.CurrentlyPay)
            {
                if (!order.IsCod)
                {
                    if (order.ShippingPayTime.HasValue)
                    {
                        throw new ArgumentException("发货人已付款，无需重复支付");
                    }
                }
                else
                {
                    int maxIndex = order.OrderExtentionInfo.Max(p => p.EndIndex);

                    if (order.OrderExtentionInfo.Single(p => p.EndIndex == maxIndex).CashedTime.HasValue)
                    {
                        throw new ArgumentException("收货人已付款，无需重复支付");
                    }
                }
            }
            else if (order.PayMode == PayMode.Collect)
            {
                if (order.ConsigneePayTime.HasValue)
                {
                    throw new ArgumentException("收货人已付款，无需重复支付");
                }
            }
            decimal? orderAmount;
            if (paymentRequestDto.OrderType == FlowType.TMSOrder && (order.PayMode == PayMode.Collect || order.PayMode == PayMode.CurrentlyPay))
            {
                orderAmount = order.FreightCostAmount;
                if (!orderAmount.HasValue || orderAmount.Value <= 0)
                {
                    throw new ArgumentException("该订单暂时没有待付款的费用。");
                }
            }
            else if (paymentRequestDto.OrderType == FlowType.Cod && order.PayMode == PayMode.Collect)
            {
                orderAmount = order.CodCostAmount;
                if (!orderAmount.HasValue || orderAmount.Value <= 0)
                {
                    throw new ArgumentException("该订单暂时没有代收货款的费用。");
                }
            }
            else if (paymentRequestDto.OrderType == FlowType.CodAndOrder && order.PayMode == PayMode.Collect)
            {
                orderAmount = order.FreightCostAmount + order.CodCostAmount;
                if (!orderAmount.HasValue || orderAmount.Value <= 0)
                {
                    throw new ArgumentException("该订单暂时没有运费及代收货款的费用。");
                }
            }
            else if (paymentRequestDto.OrderType == FlowType.Cod && order.PayMode == PayMode.PaidReceipt)
            {
                orderAmount = order.CodCostAmount;
                if (!orderAmount.HasValue || orderAmount.Value <= 0)
                {
                    throw new ArgumentException("该订单暂时没有代收货款的费用。");
                }
            }
            else if (paymentRequestDto.OrderType == FlowType.Cod && order.PayMode == PayMode.CurrentlyPay)
            {
                orderAmount = order.CodCostAmount;
                if (!orderAmount.HasValue || orderAmount.Value <= 0)
                {
                    throw new ArgumentException("该订单暂时没有代收货款的费用。");
                }
            }
            else
            {
                throw new ArgumentException("二维码服务不支持其他业务");
            }
            if (paymentRequestDto.OrderType != FlowType.Cod)
            {
                if (order.IsInsuredPrice)
                {
                    if (order.InsuredPriceChargeAmount.HasValue)
                    {
                        orderAmount = orderAmount + order.InsuredPriceChargeAmount.Value;
                    }
                    else
                    {
                        throw new ArgumentException("此订单保价缺少保价的费用");
                    }
                }
            }
            var paymentQRCode = channelFactoryService.GenerateQRCode(appType, paymentRequestDto.OrderType, user.UserId.ToString(), paymentRequestDto.ReferenceNumber, paymentRequestDto.OSType,
                paymentRequestDto.DeviceType, paymentRequestDto.DeviceId, paymentRequestDto.Parameters, orderAmount.Value, paymentRequestDto.Payer, user);
            paymentQRCode.Amount = orderAmount.Value;
            //服务费：搬家服务费，特殊服务费
            if (paymentRequestDto.OrderType == FlowType.Service)
            {
                if (order.SpecificServiceAmount.HasValue)
                {
                    paymentQRCode.Bill.Add("特殊服务费", order.SpecificServiceAmount.Value);

                }
                if (order.MoveHouseServiceAmount.HasValue)
                {
                    paymentQRCode.Bill.Add("搬家服务费", order.MoveHouseServiceAmount.Value);
                }
                if (order.CarryServiceAmount.HasValue)
                {
                    paymentQRCode.Bill.Add("搬运服务费", order.CarryServiceAmount.Value);
                }
            }
            if (paymentRequestDto.OrderType == FlowType.TMSOrder)
            {
                if (order.IsInsuredPrice)
                {
                    paymentQRCode.Bill.Add("保价", order.InsuredPriceChargeAmount.Value);
                    paymentQRCode.Bill.Add("运费", order.FreightCostAmount.Value);
                }
                else
                {
                    paymentQRCode.Bill.Add("运费", orderAmount.Value);
                }

            }
            else if (paymentRequestDto.OrderType == FlowType.Cod)
            {
                paymentQRCode.Bill.Add("代收货款", orderAmount.Value);
            }
            else if (paymentRequestDto.OrderType == FlowType.CodAndOrder)
            {
                if (order.IsInsuredPrice)
                {
                    paymentQRCode.Bill.Add("运费", order.FreightCostAmount.Value);
                    paymentQRCode.Bill.Add("代收货款", order.CodCostAmount.Value);
                    paymentQRCode.Bill.Add("保价", order.InsuredPriceChargeAmount.Value);
                }
                else
                {
                    paymentQRCode.Bill.Add("运费", order.FreightCostAmount.Value);
                    paymentQRCode.Bill.Add("代收货款", order.CodCostAmount.Value);
                }

            }
            return paymentQRCode;
        }

        #endregion 创建订单支付二维码

        #region 司机签收签字
        public OrderDto AcceptanceSignature(DriverDto driver, OrderAcceptanceSignatureRequestDto orderAcceptanceSignatureRequestDto)
        {
            OrderDto orderDto = this.GetOrder(orderAcceptanceSignatureRequestDto.OrderNo);
            if (orderDto == null)
            {
                throw new ArgumentException("订单信息不存在");
            }
            if (!orderDto.OrderExtentionInfo.Any(p => p.OrderExtentionId == orderAcceptanceSignatureRequestDto.OrderExtentionId))
            {
                throw new ArgumentException("订单地址信息不存在");
            }
            int maxIndex = orderDto.OrderExtentionInfo.Max(p => p.EndIndex);
            var orderExtentionDto = orderDto.OrderExtentionInfo.Single(p => p.OrderExtentionId == orderAcceptanceSignatureRequestDto.OrderExtentionId);
            if (orderExtentionDto.EndIndex == maxIndex)
            {
                if (orderDto.PayMode == PayMode.Collect)
                {
                    if (!orderDto.ConsigneePayTime.HasValue)
                    {
                        throw new ArgumentException("到付订单请先支付运费");
                    }
                }
            }
            if (orderExtentionDto.AddressType == AddressType.Take)
            {
                throw new ArgumentException("取货地无法操作订单签收");
            }
            if (orderExtentionDto.OrderStatus == OrderStatus.Acceptance)
            {
                return orderDto;
            }
            OrderExtentionEntity orderExtentionEntity = new OrderExtentionEntity()
            {
                OrderExtentionId = orderAcceptanceSignatureRequestDto.OrderExtentionId,
                OrderNo = orderAcceptanceSignatureRequestDto.OrderNo,
                AcceptanceSignature = orderAcceptanceSignatureRequestDto.AcceptanceSignature
            };
            if (!this.orderExtentionData.UpdateAcceptanceSignature(orderExtentionEntity).GetAwaiter().GetResult())
            {
                throw new ArgumentException("补充订单装货信息时失败!");
            }
            //如果当前地址为最终地点
            if (orderExtentionDto.EndIndex == maxIndex)
            {
                if (orderDto.PayMode == PayMode.Collect)
                {
                    //到付需要先完成支付，然后才可以签字，签字完成后才能够完成订单。
                    if (this.orderExtentionData.UpdateCollectPayOrderStatusComplete(orderDto.OrderNo).GetAwaiter().GetResult())
                    {
                        throw new ArgumentException("修改订单状态及订单途经点状态均为已完成时失败!");
                    }
                    //TODO:到付是否使用现金
                    this.systemFinanceFlowRecordService.WriteSystemFinanceFlowRecord(null, orderDto.OrderAmount.Value, orderDto.OrderNo, SourceFlowDirectionType.Record, FlowType.TMSOrder, PaymentChannelType.Balance);
                }
                //else if (orderDto.PayMode == PayMode.CurrentlyPay)
                //{
                //    //现付订单直接更新订单状态为已完成
                //    if (this.orderExtentionData.UpdateCurrentlyPayOrderStatusComplete(orderDto.OrderNo).GetAwaiter().GetResult())
                //    {

                //    }
                //}
                this.OrderComplete(orderDto.OrderId, orderDto.OrderNo);
            }
            else
            {
                this.pushMessageSendService.PushMessageForOrder(orderDto.OrderId, PushMessageType.Acceptance);
            }
            RemoveOrderCatch(orderDto.OrderId);

            return GetOrder(orderDto.OrderId);

        }
        #endregion

        #region 上传签收回单 
        public OrderDto AcceptanceReceiptPhoto(DriverDto driver, OrderReceiptPhotoRequestDto orderReceiptPhotoRequestDto)
        {
            OrderDto orderDto = this.GetOrder(orderReceiptPhotoRequestDto.OrderNo);
            if (orderDto == null)
            {
                throw new ArgumentException("订单信息不存在");
            }
            if (orderDto.OrderStatus == OrderStatus.Cancel)
            {
                throw new ArgumentException("订单已取消，无法完成上传签收回单操作");
            }
            if (orderDto.OrderStatus == OrderStatus.Complete)
            {
                throw new ArgumentException("订单已完成，无法完成上传签收回单操作");
            }
            if (orderDto.OrderStatus == OrderStatus.Dispatching)
            {
                throw new ArgumentException("订单未指派车辆，无法完成上传签收回单操作");
            }
            if (orderDto.DriverId != driver.DriverId)
            {
                throw new ArgumentException("您无法操作其他司机订单");
            }
            if (!orderDto.OrderExtentionInfo.Any(p => p.OrderExtentionId == orderReceiptPhotoRequestDto.OrderExtentionId))
            {
                throw new ArgumentException("订单内不存在此地址信息，无法完成上传签收回单操作");
            }
            OrderExtentionDto orderExtentionDto = orderDto.OrderExtentionInfo.Single(p => p.OrderExtentionId == orderReceiptPhotoRequestDto.OrderExtentionId);
            if (orderExtentionDto.AddressType == AddressType.Take)
            {
                throw new ArgumentException("此地址为卸货地，无法完成上传签收回单操作");
            }
            if (orderExtentionDto.OrderStatus == OrderStatus.Transporting)
            {
                throw new ArgumentException("此订单已在运输中，无需重复上传签收回单操作");
            }
            if (orderExtentionDto.OrderStatus != OrderStatus.Arrived)
            {
                throw new ArgumentException("并未到达此地址，无法完成上传签收回单操作");
            }
            int maxIndex = orderDto.OrderExtentionInfo.Max(p => p.EndIndex);
            if (orderDto.OrderExtentionInfo.Any(p => p.AddressType == AddressType.Place && p.OrderStatus == OrderStatus.Transporting))
            {
                throw new ArgumentException("存在运输中订单，无法完成上传签收回单操作");
            }

            #region 检查是否已上传签收回单

            if (!string.IsNullOrWhiteSpace(orderDto.ReceiptAcceptancePhoto))
            {
                return GetOrder(orderDto.OrderId);
            }

            #endregion 检查是否已上传签收回单

            OrderEntity orderEntity = orderDto.As<OrderEntity>();
            orderEntity.ReceiptAcceptancePhoto = orderReceiptPhotoRequestDto.ReceiptPhoto;

            databaseContext.BeginTransaction();
            if (!this.orderData.AddAcceptanceReceiptPhoto(orderEntity).GetAwaiter().GetResult())
            {
                throw new ArgumentException("保存车辆签收回单失败!");
            }
            if (!this.orderExtentionData.UpdateOrderStatusAcceptance(orderEntity.OrderNo, orderExtentionDto.OrderExtentionId).GetAwaiter().GetResult())
            {
                throw new ArgumentException("修改订单途经点为已签收时失败!");
            }
            if (!this.orderData.UpdateOrderStatusAcceptance(orderEntity.OrderId).GetAwaiter().GetResult())
            {
                throw new ArgumentException("修改订单状态为已签收时失败!");
            }
            this.pushMessageSendService.PushMessageForOrder(orderDto.OrderId, PushMessageType.Acceptance);

            if (orderDto.PayMode != PayMode.PaidReceipt)
            {
                if (orderExtentionDto.EndIndex == maxIndex)
                {
                    return this.OrderComplete(orderDto.OrderId, orderDto.OrderNo);
                }
            }
            databaseContext.Commit();
            RemoveOrderCatch(orderDto.OrderId);
            return GetOrder(orderDto.OrderId);
        }

        #endregion 上传签收回单

        #region 上传原始回单

        public OrderDto SourceReceiptPhoto(DriverDto driver, OrderReceiptPhotoRequestDto orderReceiptPhotoRequestDto)
        {
            OrderDto orderDto = this.GetOrder(orderReceiptPhotoRequestDto.OrderNo);
            if (orderDto == null)
            {
                throw new ArgumentException("订单信息不存在");
            }
            if (orderDto.OrderStatus == OrderStatus.Cancel)
            {
                throw new ArgumentException("订单已取消，无法完成设置原始回单操作");
            }
            if (orderDto.OrderStatus == OrderStatus.Complete)
            {
                throw new ArgumentException("订单已完成，无法完成设置原始回单操作");
            }
            if (orderDto.OrderStatus == OrderStatus.Dispatching)
            {
                throw new ArgumentException("订单未指派车辆，无法完成设置原始回单操作");
            }
            if (orderDto.DriverId != driver.DriverId)
            {
                throw new ArgumentException("您无法操作其他司机订单");
            }
            if (!orderDto.OrderExtentionInfo.Any(p => p.OrderExtentionId == orderReceiptPhotoRequestDto.OrderExtentionId))
            {
                throw new ArgumentException("订单内不存在此地址信息，无法完成设置原始回单操作");
            }
            OrderExtentionDto orderExtentionDto = orderDto.OrderExtentionInfo.Single(p => p.OrderExtentionId == orderReceiptPhotoRequestDto.OrderExtentionId);
            if (orderExtentionDto.AddressType == AddressType.Place)
            {
                throw new ArgumentException("此地址为卸货地，无法完成设置原始回单操作");
            }
            if (orderExtentionDto.OrderStatus == OrderStatus.Transporting)
            {
                throw new ArgumentException("此订单已在运输中，无需重复设置原始回单操作");
            }
            if (orderExtentionDto.OrderStatus != OrderStatus.Arrived)
            {
                throw new ArgumentException("并未到达此地址，无法完成设置原始回单操作");
            }
            int beginIndex = orderDto.OrderExtentionInfo.Min(p => p.EndIndex);
            if (orderDto.OrderExtentionInfo.Count(p => p.EndIndex == beginIndex) > 1)
            {
                throw new ArgumentException("订单信息错误，存在多个起始地");
            }
            if (string.IsNullOrWhiteSpace(orderExtentionDto.LoadPhotoShipping))
            {
                throw new ArgumentException("请先完成装货信息补充");
            }

            #region 检查原始回单

            if (!string.IsNullOrWhiteSpace(orderDto.ReceiptPhoto))
            {
                return GetOrder(orderDto.OrderId);
            }

            #endregion 检查原始回单

            OrderEntity orderEntity = orderDto.As<OrderEntity>();
            orderEntity.ReceiptPhoto = orderReceiptPhotoRequestDto.ReceiptPhoto;
            if (this.orderData.AddSourceReceiptPhoto(orderEntity).GetAwaiter().GetResult())
            {
                RemoveOrderCatch(orderDto.OrderId);
                OrderStartOutRequestDto orderStartOutRequestDto = new OrderStartOutRequestDto()
                {
                    OrderExtentionId = orderReceiptPhotoRequestDto.OrderExtentionId,
                    OrderNo = orderReceiptPhotoRequestDto.OrderNo,
                    AddressType = AddressType.Take
                };
                return StartOut(driver, orderStartOutRequestDto);
            }
            return GetOrder(orderDto.OrderId);
        }

        #endregion 设置原始回单        

        #region 验签完成处理订单信息

        public OrderDto CheckSignCompleteToProcessOrderInformation(OrderPayer payer, string orderNo, long paymentRecordId, PaymentChannelType payChannelType, decimal amount)
        {
            //此方法仅处理支付异步回调或手动验证支付结果调用
            OrderDto order = this.GetOrder(orderNo);
            if (order == null)
            {
                throw new ArgumentException("订单信息不存在");
            }
            if (order.OrderExtentionInfo == null || !order.OrderExtentionInfo.Any())
            {
                throw new ArgumentException("订单地址信息错误");
            }
            if (!order.DriverId.HasValue)
            {
                throw new ArgumentException("订单并未被接单，无法执行操作");
            }
            PaymentRecordEntity paymentRecordEntity = this.paymentRecordData.GetPaymentRecordByPaymentRecordId(paymentRecordId);
            if (paymentRecordEntity == null)
            {
                throw new ArgumentException("订单支付记录不存在");
            }
            if (!Enum.TryParse(typeof(PaymentResultType), paymentRecordEntity.Status, true, out object paymentResultType))
            {
                throw new ArgumentException("支付记录状态不是有效的状态");
            }
            if ((PaymentResultType)paymentResultType != PaymentResultType.Success)
            {
                PaymentRecordEntity paymentRecordSuccess = null;
                while (paymentRecordSuccess == null)
                {
                    paymentRecordSuccess = this.paymentRecordData.SetAsSuccess(paymentRecordId);
                }
            }

            if (order.PayMode == PayMode.CurrentlyPay)
            {
                //检查发货人付款时间是否已更新，已更新，代表已经处理过，跳过即可
                if (!order.ShippingPayTime.HasValue)
                {
                    int beginIndex = order.OrderExtentionInfo.Min(p => p.EndIndex);
                    OrderExtentionDto orderExtentionDto = order.OrderExtentionInfo.Single(p => p.EndIndex == beginIndex);
                    OrderStartOutRequestDto orderStartOutRequestDto = new OrderStartOutRequestDto()
                    {
                        OrderExtentionId = orderExtentionDto.OrderExtentionId,
                        OrderNo = order.OrderNo,
                        AddressType = AddressType.Take
                    };

                    databaseContext.BeginTransaction();
                    //写入用户流水记录
                    WriteUserFlowRecord(order.UserId, paymentRecordEntity.Amount, paymentRecordEntity.ReferenceNumber, SourceFlowDirectionType.Outlay, FlowType.TMSOrder, paymentRecordEntity.PaymentChannelId);

                    if (this.orderExtentionData.UpdateOrderStatusTransporting(orderStartOutRequestDto.OrderNo, orderStartOutRequestDto.OrderExtentionId).GetAwaiter().GetResult())
                    {
                        throw new ArgumentException("修改订单途经点状态为运输中时失败!");
                    }
                    //int status = 0;
                    //if (orderExtentionDto.EndIndex == beginIndex)
                    //{
                    //    //TODO:
                    //    //var vehicleTransportRecord = this.vehicleTransportRecordData.Get(order.VehicleId.Value, order.OrderNo).GetAwaiter().GetResult();
                    //    //if (vehicleTransportRecord != null)
                    //    //{
                    //    //    while (status == 0)
                    //    //    {
                    //    //        status = this.vehicleTransportRecordData.UpdateOrderVehicleStartOutTime(vehicleTransportRecord.VehicleTransportBatchId, order.OrderNo).GetAwaiter().GetResult();
                    //    //    }
                    //    //}
                    //}
                    if (this.orderData.UpdateOrderStatusTransporting(order.OrderId).GetAwaiter().GetResult())
                    {
                        throw new ArgumentException("修改订单状态为运输中时失败!");
                    }
                    if (order.OrderExtentionInfo.Count(p => p.AddressType == AddressType.Take) == 1 || order.OrderExtentionInfo.Any(p => p.AddressType == AddressType.Take && p.OrderStatus == OrderStatus.Transporting))
                    {
                        if (!this.orderExtentionData.UpdateOrderStatusTransporting(orderStartOutRequestDto.OrderNo).GetAwaiter().GetResult())
                        {
                            throw new ArgumentException("修改订单状态为运输中时失败!");
                        }
                    }
                    databaseContext.Commit();
                    RemoveOrderCatch(order.OrderId);
                    this.pushMessageSendService.PushMessageForOrder(order.OrderId, PushMessageType.Paid);
                }
            }
            else if (order.PayMode == PayMode.Collect)
            {
                if (!order.ConsigneePayTime.HasValue)
                {
                    int endIndex = order.OrderExtentionInfo.Max(p => p.EndIndex);
                    OrderExtentionDto orderExtentionDto = order.OrderExtentionInfo.Single(p => p.EndIndex == endIndex);

                    if (orderExtentionDto.AddressType != AddressType.Place)
                    {
                        throw new ArgumentException("此处不是卸货地，不允许执行此操作");
                    }
                    databaseContext.BeginTransaction();
                    //写入系统流水记录
                    this.systemFinanceFlowRecordService.WriteSystemFinanceFlowRecord(null, paymentRecordEntity.Amount, paymentRecordEntity.ReferenceNumber, SourceFlowDirectionType.Income, FlowType.TMSOrder, paymentRecordEntity.PaymentChannelId);

                    if (order.IsCod)
                    {
                        if (!this.orderExtentionData.UpdateCashedTime(order.OrderNo, orderExtentionDto.OrderExtentionId).GetAwaiter().GetResult())
                        {
                            throw new ArgumentException("修改订单代收货款时间时失败!");
                        }
                        this.pushMessageSendService.PushMessageForOrder(order.OrderId, PushMessageType.POS);
                    }
                    if (!this.orderData.UpdateOrderConsigneePayTime(order.OrderId).GetAwaiter().GetResult())
                    {
                        throw new ArgumentException("修改订单收货人付款时间时失败!");
                    }
                    databaseContext.Commit();
                    RemoveOrderCatch(order.OrderId);
                    return GetOrder(order.OrderId);
                }
            }
            else if (order.PayMode == PayMode.PaidReceipt)
            {
                if (!order.ShippingPayTime.HasValue)
                {
                    if (this.orderData.UpdateOrderShippingPayTime(order.OrderId).GetAwaiter().GetResult())
                    {
                        throw new ArgumentException("修改订单发货人支付时间失败!");
                    }
                    //写入用户支付记录
                    WriteUserFlowRecord(order.UserId, paymentRecordEntity.Amount, paymentRecordEntity.ReferenceNumber, SourceFlowDirectionType.Outlay, FlowType.TMSOrder, paymentRecordEntity.PaymentChannelId);

                    return this.OrderComplete(order.OrderId, orderNo);
                }
            }

            //this.orderData.UpdateOrderPayment(p => p.OrderNo == order.OrderNo, order);

            return order;
        }

        #endregion 验签完成处理订单信息


        #region 修改代收货款状态及时间

        /// <summary>
        /// 修改代收货款状态及时间
        /// </summary>
        /// <param name="orderNo">订单编号</param>
        /// <param name="paymentRecordId">支付记录Id</param>
        /// <returns></returns>
        public OrderDto UpdateCodStatusAndTime(string orderNo, long paymentRecordId)
        {
            OrderDto order = this.GetOrder(orderNo);
            return this.UpdateCodStatusAndTime(order.OrderId, paymentRecordId);
        }

        /// <summary>
        /// 修改代收货款状态及时间
        /// </summary>
        /// <param name="orderId">订单Id</param>
        /// <param name="paymentRecordId">支付记录Id</param>
        /// <returns></returns>
        public OrderDto UpdateCodStatusAndTime(long orderId, long paymentRecordId)
        {
            OrderDto order = this.GetOrder(orderId);
            if (order == null)
            {
                throw new ArgumentException("订单信息不存在");
            }
            if (order.OrderExtentionInfo == null || !order.OrderExtentionInfo.Any())
            {
                throw new ArgumentException("订单地址信息错误");
            }
            if (!order.DriverId.HasValue)
            {
                throw new ArgumentException("订单并未被接单，无法执行操作");
            }
            PaymentRecordEntity paymentRecordEntity = this.paymentRecordData.GetPaymentRecordByPaymentRecordId(paymentRecordId);
            if (paymentRecordEntity == null)
            {
                throw new ArgumentException("订单支付记录不存在");
            }
            if (!Enum.TryParse(typeof(PaymentResultType), paymentRecordEntity.Status, true, out object paymentResultType))
            {
                throw new ArgumentException("支付记录状态不是有效的状态");
            }

            if (!order.IsCod)
            {
                throw new ArgumentException("订单不存在代收货款");
            }
            databaseContext.BeginTransaction();
            if ((PaymentResultType)paymentResultType != PaymentResultType.Success)
            {
                PaymentRecordEntity paymentRecordSuccess = this.paymentRecordData.SetAsSuccess(paymentRecordId);
                if (paymentRecordSuccess == null)
                {
                    throw new ArgumentException("修改支付记录状态为成功时失败!");
                }
            }


            int endIndex = order.OrderExtentionInfo.Max(p => p.EndIndex);
            OrderExtentionDto orderExtentionDto = order.OrderExtentionInfo.Single(p => p.EndIndex == endIndex);
            if (!orderExtentionDto.CashedTime.HasValue)
            {
                if (!this.orderExtentionData.UpdateCashedTime(order.OrderNo, orderExtentionDto.OrderExtentionId).GetAwaiter().GetResult())
                {
                    throw new ArgumentException("修改订单代收货款时间时失败!");
                }
                this.pushMessageSendService.PushMessageForOrder(order.OrderId, PushMessageType.POS);
            }
            databaseContext.Commit();
            RemoveOrderCatch(order.OrderId);

            return GetOrder(order.OrderId);
        }

        #endregion 修改代收货款状态及时间


        #region 订单签收
        public OrderDto OrderSign(DriverDto driver, OrderSignPersonRequestDto orderSignPersonRequestDto)
        {
            OrderDto orderDto = this.GetOrder(orderSignPersonRequestDto.OrderNo);
            if (orderDto == null)
            {
                throw new ArgumentException("订单信息不存在");
            }
            if (orderDto.OrderStatus == OrderStatus.Cancel)
            {
                throw new ArgumentException("订单已取消，无法完成出发操作");
            }
            if (orderDto.OrderStatus == OrderStatus.Complete)
            {
                throw new ArgumentException("订单已完成，无法完成出发操作");
            }
            if (orderDto.DriverId != driver.DriverId)
            {
                throw new ArgumentException("您无法操作其他司机订单");
            }
            if (!orderDto.OrderExtentionInfo.Any(p => p.OrderExtentionId == orderSignPersonRequestDto.OrderExtentionId))
            {
                throw new ArgumentException("订单内不存在此地址信息，无法完成签收操作");
            }
            OrderExtentionDto orderExtentionDto = orderDto.OrderExtentionInfo.Single(p => p.OrderExtentionId == orderSignPersonRequestDto.OrderExtentionId);
            if (orderExtentionDto.AddressType == AddressType.Take)
            {
                throw new ArgumentException("此地址为取货地，无法完成签收操作");
            }
            if (orderExtentionDto.OrderStatus != OrderStatus.Arrived)
            {
                throw new ArgumentException("并未到达此地址，无法完成签收操作");
            }
            int maxIndex = orderDto.OrderExtentionInfo.Max(p => p.EndIndex);
            if (orderDto.OrderExtentionInfo.Any(p => p.AddressType == AddressType.Place && p.OrderStatus == OrderStatus.Transporting))
            {
                throw new ArgumentException("存在运输中订单，无法完成签收操作");
            }

            OrderEntity orderEntity = orderDto.As<OrderEntity>();
            orderEntity.OrderSignTime = DateTime.Now;
            orderEntity.OrderSignPerson = orderSignPersonRequestDto.OrderSignPerson;
            orderEntity.OrderSignPhoto = orderSignPersonRequestDto.OrderSignPhotos.Any() ? string.Join(",", orderSignPersonRequestDto.OrderSignPhotos) : string.Empty;
            databaseContext.BeginTransaction();
            if (!this.orderData.UpdateOrderSignPersonInfo(orderEntity).GetAwaiter().GetResult())
            {
                throw new ArgumentException("修改订单签收人信息时失败!");
            }
            if (!this.orderData.UpdateOrderStatusAcceptance(orderEntity.OrderId).GetAwaiter().GetResult())
            {
                throw new ArgumentException("修改订单状态为已签收时失败!");
            }

            this.OrderComplete(orderDto.OrderId, orderDto.OrderNo);
            this.pushMessageSendService.PushMessageForOrder(orderDto.OrderId, PushMessageType.Complete);
            databaseContext.Commit();

            RemoveOrderCatch(orderDto.OrderId);
            return GetOrder(orderDto.OrderId);
        }
        #endregion

        #endregion


        public PageableList<OrderDto> Query(AdminDto adminDto, string orderNo, string vehicleNo, string provinceCode, string cityCode, string countyCode, OrderStatus? orderStatus,
            string goodsName, long? userId, long? driverId, string endProvinceCode, string endCityCode, string endCountyCode, decimal? goodsWeightLeft, decimal? goodsWeightRight,
            int? vehicleTypeId, TransportBusinessType? transportBusinessType, string vehicleCategoryName, string phone, DateTime? start, DateTime? end, bool? ascending, int pageIndex = 1,
            int pageSize = 20)
        {
            if (string.IsNullOrWhiteSpace(orderNo))
            {
                string orderEntityKey = this.redisService.GetKey("{0}:Query", EntityNameConst.OrderEntity, provinceCode, cityCode, countyCode, orderStatus, goodsName, userId, driverId, start,
                    end, ascending, pageIndex, pageSize, vehicleNo, endProvinceCode, endCityCode, endCountyCode, goodsWeightLeft, goodsWeightRight, vehicleTypeId, transportBusinessType,
                    vehicleCategoryName, phone);
                PageableList<OrderDto> pageableListResult = this.redisService.TryGet(orderEntityKey, () =>
                {
                    var (list, count) = this.orderData.GetOrderEntities(adminDto.CompanyId, vehicleNo, provinceCode, cityCode, countyCode, orderStatus, goodsName, userId, driverId,
                        endProvinceCode, endCityCode, endCountyCode, goodsWeightLeft, goodsWeightRight, vehicleTypeId, transportBusinessType, vehicleCategoryName, phone, start, end, ascending, pageIndex, pageSize).GetAwaiter().GetResult();

                    IEnumerable<OrderDto> orderEntities = list.As<IEnumerable<OrderDto>>();
                    foreach (OrderDto item in orderEntities)
                    {
                        item.OrderExtentionInfo = GetOrderExtentionDtos(item.OrderNo);
                    }

                    return new PageableList<OrderDto>
                    {
                        Items = orderEntities,
                        Count = count
                    };
                }, TimeSpan.FromSeconds(1));

                return pageableListResult;
            }
            else
            {
                var result = this.GetOrder(orderNo);
                PageableList<OrderDto> pageableList = new PageableList<OrderDto>()
                {
                    Items = new List<OrderDto>() { result },
                    Count = result != null ? 1 : 0
                };
                return pageableList;
            }

        }

        #region 取消订单

        public void CancelOrder(UserDto userDto, string vehicleNo, SourceAppType appType, OrderCancelRequestDto orderCancelRequestDto)
        {
            OrderDto orderDto = this.GetOrder(orderCancelRequestDto.OrderId);
            if (orderDto == null)
            {
                throw new ArgumentException("订单信息不存在");
            }
            if (orderDto.OrderStatus == OrderStatus.Cancel)
            {
                throw new ArgumentException("订单已取消，不可重复操作");
            }
            if (orderDto.OrderStatus == OrderStatus.Acceptance)
            {
                throw new ArgumentException("订单已签收，不可取消订单");
            }
            if (orderDto.OrderStatus == OrderStatus.Transporting)
            {
                throw new ArgumentException("订单已在运输中，不可取消订单");
            }
            if (orderDto.OrderStatus == OrderStatus.Complete)
            {
                throw new ArgumentException("订单已完成，不可取消订单");
            }
            if (appType == SourceAppType.ClientApp)
            {
                if (orderDto.UserId != userDto.UserId)
                {
                    throw new ArgumentException("非订单创建者，无法取消订单");
                }
            }
            else
            {
                //if (orderDto.OrderStatus == OrderStatus.Pickup)
                //{
                //    throw new ArgumentException("订单已在取货中，不可取消订单");
                //}
                if (orderDto.VehicleNo != vehicleNo)
                {
                    throw new ArgumentException("您没有接此订单，无法取消订单");
                }
            }
            var orderPool = this.orderPoolData.GetCancelOrder(orderDto.OrderId).GetAwaiter().GetResult();
            if (orderPool == null)
            {
                throw new ArgumentException("此订单不存在");
            }
            this.orderCancelRecordService.Add(orderDto.OrderId, appType != SourceAppType.ClientApp, orderCancelRequestDto.CloseOrderContent, appType != SourceAppType.ClientApp ? userDto.UserName : null);
        }

        #endregion 取消订单

        #region 获取订单扩展信息

        private List<OrderExtentionDto> GetOrderExtentionDtos(string orderNo)
        {
            string cacheKey = string.Format("{0}:OrderNo={1}", EntityNameConst.OrderExtentionEntities, orderNo);
            IEnumerable<OrderExtentionEntity> orderExtentionEntities = this.redisService.TryGet(cacheKey, () =>
            {
                var orderExtentions = this.orderExtentionData.GetList(orderNo).GetAwaiter().GetResult();
                var orderExtentionsOrders = orderExtentions.OrderBy(p => p.EndIndex);
                return orderExtentionsOrders.AsEnumerable();
            }, TimeSpan.FromDays(10));

            if (orderExtentionEntities == null || !orderExtentionEntities.Any())
            {
                this.redisService.DeleteAsync(cacheKey);
            }
            return orderExtentionEntities.As<List<OrderExtentionDto>>();
        }

        #endregion 获取订单扩展信息

        public bool AssignDriver(long orderId, long driverId, int? distance, AdminDto admin)
        {
            var order = this.orderData.GetEntity(orderId).GetAwaiter().GetResult();
            if (order == null)
            {
                throw new ArgumentException("订单信息不存在");
            }
            if (order.DriverId.HasValue)
            {
                throw new ArgumentException("订单已被指派不能重复指派");
            }
            var driver = this.driverData.GetDriverByIdAsync(driverId).GetAwaiter().GetResult();
            if (driver == null)
            {
                throw new ArgumentException("司机信息不存在");
            }
            if (order.VehicleTypeId != driver.VehicleTypeId)
            {
                throw new ArgumentException("司机的车型不符订单要求，指派失败。");
            }
            if (driver.RealNameVerifiesStatus != RealNameVerifiesStatus.Success.ToString())
            {
                throw new ArgumentException("司机实名认证未通过，无法指派订单");
            }
            if (driver.DriverStatus != DriverStatus.Success)
            {
                throw new ArgumentException("司机车辆审核未通过，无法指派订单");
            }
            if (driver.WorkingStatus == DriverWorkingStatus.Stopped)
            {
                throw new ArgumentException("车辆已被停止服务，无法指派订单");
            }
            databaseContext.BeginTransaction();

            if (!this.orderData.UpdateOrderAssigned(order.OrderId, driver.DriverId, driver.Name, driver.Phone, driver.VehicleNo, OrderStatus.Pickup, admin.AdminId, admin.FullName).GetAwaiter().GetResult())
            {
                throw new ArgumentException("订单指派失败。");
            }
            if (!this.orderExtentionData.UpdateOrderStatusPickup(order.OrderNo).GetAwaiter().GetResult())
            {
                throw new ArgumentException("订单指派失败。");
            }
            OrderEvaluationDto orderEvaluationDto = this.orderEvaluationService.Create(orderId);
            if (orderEvaluationDto == null)
            {
                throw new ArgumentException("订单指派失败。");
            }
            // 增加订单指派记录
            orderAssignRecordData.InsertAsync(new OrderAssignRecordEntity
            {

                AdminId = admin.AdminId,
                AssignEditer = admin.FullName,
                AssignTime = DateTime.Now,
                CompanyId = admin.CompanyId,
                AssignEditerId = admin.AdminId,
                DepartmentId = admin.DepartmentId.Value,
                VehicleNo = driver.VehicleNo,
                DriverId = driver.DriverId,
                DriverName = driver.Name,
                OrderId = order.OrderId,
                OrderNo = order.OrderNo,
                IsAssign = true,
                Reason = "已指派",
            }).GetAwaiter().GetResult();
            databaseContext.Commit();
            return true;
        }


        #region 移除订单缓存

        private void RemoveOrderCatch(long orderId)
        {
            string key = string.Format("{0}:OrderId={1}", EntityNameConst.OrderEntity, orderId);
            this.redisService.DeleteAsync(key);
            OrderDto order = this.GetOrder(orderId);
            key = string.Format("{0}:OrderNo={1}", EntityNameConst.OrderEntity, order.OrderNo);
            this.redisService.DeleteAsync(key);
            key = string.Format("{0}:OrderNo={1}", EntityNameConst.OrderExtentionEntities, order.OrderNo);
            this.redisService.DeleteAsync(key);
            order = this.GetOrder(orderId);
        }

        #endregion 移除订单缓存


        #region 检查订单是否已经支付
        public bool CheckOrderPaid(string orderNo)
        {
            OrderDto orderDto = this.GetOrder(orderNo);
            if (orderDto == null)
            {
                throw new ArgumentException("订单信息不存在");
            }
            if (orderDto.PayMode == PayMode.CurrentlyPay && orderDto.ShippingPayTime.HasValue)
            {
                if (orderDto.IsCod)
                {
                    int maxIndex = orderDto.OrderExtentionInfo.Max(p => p.EndIndex);
                    if (!orderDto.OrderExtentionInfo.Single(p => p.EndIndex == maxIndex).CashedTime.HasValue)
                    {
                        return false;
                    }
                }
                return true;
            }
            if (orderDto.PayMode == PayMode.Collect && orderDto.ConsigneePayTime.HasValue)
            {
                return true;
            }
            if (orderDto.PayMode == PayMode.PaidReceipt && orderDto.ShippingPayTime.HasValue)
            {
                return true;
            }
            return false;
        }
        #endregion


        #region 验签完成处理订单信息
        public OrderDto CheckSignCompleteToProcessOrderInformation(SourcePayerType payer, string orderNo, long paymentRecordId, PaymentChannelType payChannelType, decimal amount)
        {
            //此方法仅处理支付异步回调或手动验证支付结果调用
            OrderDto order = this.GetOrder(orderNo);
            if (order == null)
            {
                throw new ArgumentException("订单信息不存在");
            }
            if (order.OrderExtentionInfo == null || !order.OrderExtentionInfo.Any())
            {
                throw new ArgumentException("订单地址信息错误");
            }
            if (!order.DriverId.HasValue)
            {
                throw new ArgumentException("订单并未被接单，无法执行操作");
            }
            PaymentRecordEntity paymentRecordEntity = this.paymentRecordData.GetPaymentRecordByPaymentRecordId(paymentRecordId);
            if (paymentRecordEntity == null)
            {
                throw new ArgumentException("订单支付记录不存在");
            }
            if (!Enum.TryParse(paymentRecordEntity.Status, true, out PaymentResultType paymentResultType))
            {
                throw new ArgumentException("支付记录状态不是有效的状态");
            }

            databaseContext.BeginTransaction();
            if (paymentResultType != PaymentResultType.Success)
            {
                PaymentRecordEntity paymentRecordSuccess = this.paymentRecordData.SetAsSuccess(paymentRecordId);
                if (paymentRecordSuccess == null)
                {
                    throw new ArgumentException("修改支付记录状态为已成功时失败!");
                }
            }

            //用户端付款成功后，司机端增加提示
            if (order.DriverId.HasValue)
            {
                var driverEntity = this.driverData.GetDriverByIdAsync(order.DriverId.Value).GetAwaiter().GetResult();
                if (driverEntity != null)
                {
                    this.notificationMessageRecordData.InsertAsync(new NotificationMessageRecordEntity
                    {
                        UserId = driverEntity.UserId,
                        NotificationTitle = $"货主：{order.Shipping}已付款成功，请注意查收",
                        NotificationType = NotificationMessageRecordType.ClientPaymentSuccessful.ToString(),
                        RelatedRecordId = order.OrderId,
                        NotificationContent = $"货主：{order.Shipping}已于{DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss")}完成运费支付，请注意查收"
                    }).GetAwaiter().GetResult();
                }
            }
            if (order.PayMode == PayMode.CurrentlyPay)
            {
                //检查发货人付款时间是否已更新，已更新，代表已经处理过，跳过即可
                if (!order.ShippingPayTime.HasValue)
                {
                    int beginIndex = order.OrderExtentionInfo.Min(p => p.EndIndex);
                    OrderExtentionDto orderExtentionDto = order.OrderExtentionInfo.Single(p => p.EndIndex == beginIndex);
                    OrderStartOutRequestDto orderStartOutRequestDto = new OrderStartOutRequestDto()
                    {
                        OrderExtentionId = orderExtentionDto.OrderExtentionId,
                        OrderNo = order.OrderNo,
                        AddressType = AddressType.Take
                    };

                    //写入用户流水记录
                    if (payChannelType != PaymentChannelType.Balance)
                    {
                        WriteUserFlowRecord(order.UserId, paymentRecordEntity.Amount, paymentRecordEntity.ReferenceNumber, SourceFlowDirectionType.Outlay, FlowType.TMSOrder, paymentRecordEntity.PaymentChannelId);
                    }

                    //bool result = this.orderExtentionData.UpdateOrderStatusTransporting(orderStartOutRequestDto.OrderNo, orderStartOutRequestDto.OrderExtentionId).GetAwaiter().GetResult() > 0;
                    //if (result)
                    //{
                    //    //int status = 0;
                    //    //if (orderExtentionDto.EndIndex == beginIndex)
                    //    //{
                    //    //    var vehicleTransportRecord = this.vehicleTransportRecordData.Get(order.VehicleId.Value, order.OrderNo).GetAwaiter().GetResult();
                    //    //    if (vehicleTransportRecord != null)
                    //    //    {
                    //    //        while (status == 0)
                    //    //        {
                    //    //            status = this.vehicleTransportRecordData.UpdateOrderVehicleStartOutTime(vehicleTransportRecord.VehicleTransportBatchId, order.OrderNo).GetAwaiter().GetResult();
                    //    //        }
                    //    //    }
                    //    //}
                    //    int status = 0;
                    //    while (status == 0)
                    //    {
                    //        status = this.orderData.UpdateOrderStatusTransporting(order.OrderId).GetAwaiter().GetResult();
                    //    }
                    //    if (order.OrderExtentionInfo.Count(p => p.AddressType == AddressType.Take) == 1 || order.OrderExtentionInfo.Any(p => p.AddressType == AddressType.Take && p.OrderStatus == OrderStatus.Transporting))
                    //    {
                    //        status = 0;
                    //        while (status == 0)
                    //        {
                    //            status = this.orderExtentionData.UpdateOrderStatusTransporting(orderStartOutRequestDto.OrderNo).GetAwaiter().GetResult();
                    //        }
                    //    }
                    //    RemoveOrderCatch(order.OrderId);
                    //    this.pushMessageSendService.PushMessageForOrder(order.OrderId, PushMessageType.Paid);
                    //}
                    if (!this.orderData.UpdateOrderShippingPayTime(order.OrderId).GetAwaiter().GetResult())
                    {
                        throw new ArgumentException("修改订单发货人支付时间失败!");
                    }
                    if (this.orderPoolData.UpdateIsAssignReady(order.OrderId).GetAwaiter().GetResult())
                    {
                        throw new ArgumentException("修改订单是否指派已就绪时失败!");
                    }
                    databaseContext.Commit();
                    return GetOrder(order.OrderId);
                }
            }
            else if (order.PayMode == PayMode.Collect)
            {
                if (!order.ConsigneePayTime.HasValue)
                {
                    int endIndex = order.OrderExtentionInfo.Max(p => p.EndIndex);
                    OrderExtentionDto orderExtentionDto = order.OrderExtentionInfo.Single(p => p.EndIndex == endIndex);

                    if (orderExtentionDto.AddressType != AddressType.Place)
                    {
                        throw new ArgumentException("此处不是卸货地，不允许执行此操作");
                    }
                    //写入系统流水记录
                    this.systemFinanceFlowRecordService.WriteSystemFinanceFlowRecord(null, paymentRecordEntity.Amount, paymentRecordEntity.ReferenceNumber, SourceFlowDirectionType.Income, FlowType.TMSOrder, paymentRecordEntity.PaymentChannelId);

                    bool result = false;
                    if (order.IsCod)
                    {
                        if (!this.orderExtentionData.UpdateCashedTime(order.OrderNo, orderExtentionDto.OrderExtentionId).GetAwaiter().GetResult())
                        {
                            throw new ArgumentException("修改订单代收货款时间时失败!");
                        }
                        this.pushMessageSendService.PushMessageForOrder(order.OrderId, PushMessageType.POS);
                    }
                    if (!this.orderData.UpdateOrderConsigneePayTime(order.OrderId).GetAwaiter().GetResult())
                    {
                        throw new ArgumentException("修改订单收货人付款时间时失败!");
                    }
                    databaseContext.Commit();
                    RemoveOrderCatch(order.OrderId);
                    return GetOrder(order.OrderId);
                }
            }
            else if (order.PayMode == PayMode.PaidReceipt)
            {
                if (!order.ShippingPayTime.HasValue)
                {
                    if (!this.orderData.UpdateOrderShippingPayTime(order.OrderId).GetAwaiter().GetResult())
                    {
                        throw new ArgumentException("修改订单发货人支付时间失败!");
                    }

                    //写入用户支付记录
                    if (payChannelType != PaymentChannelType.Balance)
                    {
                        WriteUserFlowRecord(order.UserId, paymentRecordEntity.Amount, paymentRecordEntity.ReferenceNumber, SourceFlowDirectionType.Outlay, FlowType.TMSOrder, paymentRecordEntity.PaymentChannelId);
                    }

                    order = this.OrderComplete(order.OrderId, orderNo);
                    databaseContext.Commit();
                    return order;
                }
            }

            //this.orderData.UpdateOrderPayment(p => p.OrderNo == order.OrderNo, order);

            return order;
        }

        #endregion 验签完成处理订单信息


        #region 更新订单状态为完成，并发起结算通知

        public OrderDto OrderComplete(long orderId, string orderNo)
        {
            OrderDto orderDto = GetOrder(orderId);
            if (orderDto.IsCod)
            {
                int maxIndex = orderDto.OrderExtentionInfo.Max(p => p.EndIndex);
                OrderExtentionDto orderExtentionDto = orderDto.OrderExtentionInfo.Single(p => p.EndIndex == maxIndex);
                if (!orderExtentionDto.CashedTime.HasValue)
                {
                    throw new ArgumentException("代收货款未收款，无法完成订单");
                }
            }

            if (orderDto.PayMode == PayMode.PaidReceipt)
            {
                RemoveOrderCatch(orderId);
                orderDto = GetOrder(orderId);
                if (!orderDto.ShippingPayTime.HasValue)
                {
                    throw new ArgumentException("回单付订单未支付运费，无法完成订单");
                }
            }
            OrderStatus orderStatus = orderDto.OrderStatus;
            if (orderStatus != OrderStatus.Complete)
            {
                lock (orderDto)
                {
                    if (!this.orderData.UpdateOrderStatusComplete(orderId, orderNo).GetAwaiter().GetResult())
                    {
                        throw new ArgumentException("订单完成时失败!");
                    }
                    //var vehicleTransportRecord = this.vehicleTransportRecordData.Get(orderDto.VehicleId.Value, orderDto.OrderNo).GetAwaiter().GetResult();
                    //if (vehicleTransportRecord != null)
                    //{
                    //    status = 0;
                    //    while (status == 0)
                    //    {
                    //        status = this.vehicleTransportRecordData.UpdateOrderCompleteTime(vehicleTransportRecord.VehicleTransportBatchId, orderDto.OrderNo).GetAwaiter().GetResult();
                    //    }

                    //    int checkResult = this.vehicleTransportRecordData.CheckOrderNotCompleteExists(vehicleTransportRecord.VehicleTransportBatchNo).GetAwaiter().GetResult();
                    //    //订单如果已到达，会更新运输批次中此订单的IsDone字段为true，所以，查询结果如果为0，标识所有的订单都已经到达，此方法排除了司机忽略的订单。
                    //    if (checkResult == 0)
                    //    {
                    //        status = 0;
                    //        while (status == 0)
                    //        {
                    //            status = this.vehicleTransportRecordData.UpdateVehicleTotalWorkEffectiveTime(vehicleTransportRecord.VehicleTransportRecordId).GetAwaiter().GetResult();
                    //        }
                    //    }
                    //}

                    //TODO:准备调用资金收益划分
                    //if (!this.orderSettlementService.Settlement(orderId))
                    //{
                    //    status = 0;
                    //    while (status == 0)
                    //    {
                    //        status = this.orderData.RollbackOrderStatus(orderId, orderNo, orderStatus).GetAwaiter().GetResult();
                    //    }
                    //    throw new ArgumentException("订单结算异常，请重试");
                    //}


                    //status = 0;
                    //while (status == 0)
                    //{
                    //    status = this.orderInfoFeeRecordData.UpdateStatus(orderDto.OrderNo, OrderInfoFeeEndStatus.OrderFinish).GetAwaiter().GetResult();
                    //}
                    //this.vehicleOrderDailyReportData.CalculateReport(orderDto.OrderNo);
                    //this.userOrderMonthlyReportData.CreateOrUpdate(orderDto.UserId);
                    RemoveOrderCatch(orderId);
                    this.pushMessageSendService.PushMessageForOrder(orderDto.OrderId, PushMessageType.Complete);
                }
            }
            return GetOrder(orderId);
        }

        #endregion 更新订单状态为完成，并发起结算通知

        #region 写入用户流水记录
        /// <summary>
        /// 写入用户流水记录
        /// </summary>
        /// <param name="userId">用户Id(资金流水相关人)</param>
        /// <param name="amount">金额</param>
        /// <param name="orderNo">订单编号</param>
        /// <param name="flowDirectionType">资金流水方向</param>
        /// <param name="flowType">资金流水类型</param>
        /// <param name="payChannelType">支付渠道类型</param>
        /// <returns></returns>
        private UserFlowRecordEntity WriteUserFlowRecord(long userId, decimal amount, string orderNo, SourceFlowDirectionType flowDirectionType, FlowType flowType, PaymentChannelType payChannelType)
        {
            WalletDto walletDto = this.walletService.GetWalletByUserId(userId);
            UserEntity userEntity = this.userData.GetUserByUserId(userId).GetAwaiter().GetResult();
            UserFlowRecordEntity userFlowRecordEntity = new UserFlowRecordEntity
            {
                Balance = flowDirectionType == SourceFlowDirectionType.Income ? walletDto.Balance + amount : walletDto.Balance - amount,
                Amount = flowDirectionType == SourceFlowDirectionType.Income ? amount : -amount,
                OrderNo = orderNo,
                CreateTime = DateTime.Now,
                Remark = $"{flowType.GetDescriptionString()}: {string.Format("{0:n2}", (flowDirectionType == SourceFlowDirectionType.Income ? +amount : -amount))}元",
                FlowDirection = flowDirectionType,
                FlowType = flowType,
                Channel = payChannelType,
                UserId = userId,
                UserName = userEntity.UserName
            };
            SystemFinanceFlowRecordDto systemFinanceFlowRecordDto = null;
            while (systemFinanceFlowRecordDto == null)
            {
                systemFinanceFlowRecordDto = this.systemFinanceFlowRecordService.WriteSystemFinanceFlowRecord(userId, amount, orderNo, SourceFlowDirectionType.Income, flowType, payChannelType);
            }
            UserFlowRecordEntity userFlowRecordEntityResult = null;
            while (userFlowRecordEntityResult == null)
            {
                userFlowRecordEntityResult = userFlowRecordData.AddAsync(userFlowRecordEntity).GetAwaiter().GetResult();
            }
            return userFlowRecordEntityResult;
        }

        #endregion
    }
}
